"""DHCP数据模式."""

from datetime import datetime
from ipaddress import IPv4Address, IPv4Network
from typing import Optional, List, Dict, Any

from pydantic import BaseModel, Field, validator


class DHCPScopeBase(BaseModel):
    """DHCP作用域基础模式."""
    
    name: str = Field(..., description="作用域名称")
    network: str = Field(..., description="网络地址")
    subnet_mask: str = Field(..., description="子网掩码")
    start_ip: str = Field(..., description="起始IP地址")
    end_ip: str = Field(..., description="结束IP地址")
    gateway: Optional[str] = Field(None, description="默认网关")
    dns_servers: List[str] = Field(default_factory=list, description="DNS服务器列表")
    domain_name: Optional[str] = Field(None, description="域名")
    lease_time: int = Field(86400, description="租约时间(秒)")
    description: Optional[str] = Field(None, description="描述信息")
    is_active: bool = Field(True, description="是否激活")

    @validator("network")
    def validate_network(cls, v):
        try:
            IPv4Network(v)
            return v
        except ValueError:
            raise ValueError("Invalid network format")

    @validator("start_ip", "end_ip", "gateway")
    def validate_ip(cls, v):
        if v is None:
            return v
        try:
            IPv4Address(v)
            return v
        except ValueError:
            raise ValueError("Invalid IP address format")


class DHCPScopeCreate(DHCPScopeBase):
    """DHCP作用域创建模式."""
    pass


class DHCPScopeUpdate(BaseModel):
    """DHCP作用域更新模式."""
    
    gateway: Optional[str] = Field(None, description="默认网关")
    dns_servers: Optional[List[str]] = Field(None, description="DNS服务器列表")
    domain_name: Optional[str] = Field(None, description="域名")
    lease_time: Optional[int] = Field(None, description="租约时间(秒)")
    description: Optional[str] = Field(None, description="描述信息")
    is_active: Optional[bool] = Field(None, description="是否激活")


class DHCPScopeResponse(DHCPScopeBase):
    """DHCP作用域响应模式."""
    
    id: int = Field(..., description="作用域ID")
    total_ips: int = Field(..., description="总IP数")
    used_ips: int = Field(..., description="已用IP数")
    available_ips: int = Field(..., description="可用IP数")
    utilization: float = Field(..., description="使用率")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        orm_mode = True


class DHCPReservationBase(BaseModel):
    """DHCP保留地址基础模式."""
    
    scope_id: int = Field(..., description="作用域ID")
    ip_address: str = Field(..., description="保留的IP地址")
    mac_address: str = Field(..., description="MAC地址")
    hostname: Optional[str] = Field(None, description="主机名")
    description: Optional[str] = Field(None, description="描述信息")
    is_active: bool = Field(True, description="是否激活")

    @validator("ip_address")
    def validate_ip(cls, v):
        try:
            IPv4Address(v)
            return v
        except ValueError:
            raise ValueError("Invalid IP address format")

    @validator("mac_address")
    def validate_mac(cls, v):
        import re
        pattern = r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"
        if not re.match(pattern, v):
            raise ValueError("Invalid MAC address format")
        return v.upper().replace("-", ":")


class DHCPReservationCreate(DHCPReservationBase):
    """DHCP保留地址创建模式."""
    pass


class DHCPReservationUpdate(BaseModel):
    """DHCP保留地址更新模式."""
    
    hostname: Optional[str] = Field(None, description="主机名")
    description: Optional[str] = Field(None, description="描述信息")
    is_active: Optional[bool] = Field(None, description="是否激活")


class DHCPReservationResponse(DHCPReservationBase):
    """DHCP保留地址响应模式."""
    
    id: int = Field(..., description="保留地址ID")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        orm_mode = True


class DHCPLeaseBase(BaseModel):
    """DHCP租约基础模式."""
    
    scope_id: int = Field(..., description="作用域ID")
    ip_address: str = Field(..., description="分配的IP地址")
    mac_address: str = Field(..., description="客户端MAC地址")
    hostname: Optional[str] = Field(None, description="客户端主机名")
    lease_start: datetime = Field(..., description="租约开始时间")
    lease_end: datetime = Field(..., description="租约结束时间")
    state: str = Field("active", description="租约状态")


class DHCPLeaseCreate(DHCPLeaseBase):
    """DHCP租约创建模式."""
    pass


class DHCPLeaseUpdate(BaseModel):
    """DHCP租约更新模式."""
    
    hostname: Optional[str] = Field(None, description="客户端主机名")
    lease_end: Optional[datetime] = Field(None, description="租约结束时间")
    state: Optional[str] = Field(None, description="租约状态")


class DHCPLeaseResponse(DHCPLeaseBase):
    """DHCP租约响应模式."""
    
    id: int = Field(..., description="租约ID")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        orm_mode = True


class DHCPAllocationRequest(BaseModel):
    """DHCP地址分配请求."""
    
    scope_id: int = Field(..., description="作用域ID")
    mac_address: str = Field(..., description="客户端MAC地址")
    hostname: Optional[str] = Field(None, description="客户端主机名")
    requested_ip: Optional[str] = Field(None, description="请求的IP地址")


class DHCPAllocationResponse(BaseModel):
    """DHCP地址分配响应."""
    
    ip_address: str = Field(..., description="分配的IP地址")
    subnet_mask: str = Field(..., description="子网掩码")
    gateway: Optional[str] = Field(None, description="默认网关")
    dns_servers: List[str] = Field(..., description="DNS服务器列表")
    domain_name: Optional[str] = Field(None, description="域名")
    lease_time: int = Field(..., description="租约时间(秒)")
    lease_start: datetime = Field(..., description="租约开始时间")
    lease_end: datetime = Field(..., description="租约结束时间")


class DHCPStatistics(BaseModel):
    """DHCP统计信息."""
    
    total_scopes: int = Field(..., description="总作用域数")
    active_scopes: int = Field(..., description="活跃作用域数")
    total_leases: int = Field(..., description="总租约数")
    active_leases: int = Field(..., description="活跃租约数")
    expired_leases: int = Field(..., description="过期租约数")
    reserved_ips: int = Field(..., description="保留地址数")
    utilization: float = Field(..., description="整体使用率")